format ELF64 executable 3
entry Start
;-------------------------------------------------------------------------------
segment readable executable
;-------------------------------------------------------------------------------
; NAME:         ComputeColor
; IN:           xmm0.xyzw   normalized x coordinate (replicated)
; IN:           xmm1.xyzw   normalized y coordinate (replicated)
; OUT:          xmm0.xyz    pixel color
;-------------------------------------------------------------------------------
align 16
ComputeColor:
                sub         rsp,8
                movaps      xmm0,dqword [g_1_0]
                add         rsp,8
                ret
;-------------------------------------------------------------------------------
; NAME:         Start
; DESC:         Program entry point.
;-------------------------------------------------------------------------------
Start:
imgptr          equ         rbp-8
x               equ         rbp-12
y               equ         rbp-16
                mov         rbp,rsp
                sub         rsp,32
                ; alloc memory for the image
                mov         eax,9             ; sys_mmap
                xor         edi,edi           ; addr
                mov         esi,IMG_W*IMG_H*4 ; length
                mov         edx,0x1+0x2       ; PROT_READ | PROT_WRITE
                mov         r10d,0x02+0x20    ; MAP_PRIVATE | MAP_ANONYMOUS
                mov         r8,-1             ; fd
                xor         r9d,r9d           ; offset
                syscall
                mov         [imgptr],rax
                mov         rbx,rax
                ; begin loops
                mov         dword [y],0
.LoopY:
                mov         dword [x],0
.LoopX:
                ; compute normalized x coordinate [-1.0 , 1.0]
                cvtsi2ss    xmm0,[x]
                divss       xmm0,[g_img_w]
                shufps      xmm0,xmm0,0x00
                subps       xmm0,dqword [g_0_5]
                addps       xmm0,xmm0
                ; compute normalized y coordinate [-1.0 , 1.0]
                cvtsi2ss    xmm1,[y]
                divss       xmm1,[g_img_h]
                shufps      xmm1,xmm1,0x00
                subps       xmm1,dqword [g_0_5]
                addps       xmm1,xmm1
                call        ComputeColor
                ; clamp to [0.0 , 1.0]
                maxps       xmm0,dqword [g_0_0]
                minps       xmm0,dqword [g_1_0]
                ; convert from [0.0 , 1.0] to [0 , 255]
                mulps       xmm0,dqword [g_255_0]
                cvttps2dq   xmm0,xmm0
                pshufb      xmm0,dqword [g_img_conv_mask]
                ; set alpha to 0xff
                movd        eax,xmm0
                or          eax,0xff000000
                mov         [rbx],eax
                ; advance pixel pointer
                add         rbx,4
                ; continue .LoopX
                inc         dword [x]
                cmp         dword [x],IMG_W
                jne         .LoopX
                ; continue .LoopY
                inc         dword [y]
                cmp         dword [y],IMG_H
                jne         .LoopY
                ; create TGA file
                mov         eax,85
                mov         rdi,g_tga_name
                mov         esi,110000000b
                syscall
                mov         rbx,rax
                ; write header
                mov         eax,1
                mov         rdi,rbx
                mov         rsi,g_tga_head
                mov         edx,18
                syscall
                ; write pixel data
                mov         eax,1
                mov         rdi,rbx
                mov         rsi,[imgptr]
                mov         edx,IMG_W*IMG_H*4
                syscall
                ; terminate process
                mov         eax,60
                xor         edi,edi
                syscall
                restore     imgptr,x,y
;-------------------------------------------------------------------------------
segment readable
;-------------------------------------------------------------------------------
align 1
g_tga_name      db          'phong.tga',0
g_tga_head      db          0,0,2,9 dup 0
                db          (IMG_W and 0x00ff),(IMG_W and 0xff00) shr 8
                db          (IMG_H and 0x00ff),(IMG_H and 0xff00) shr 8,32,0
IMG_W=800
IMG_H=800
align 4
g_img_w         dd          800.0
g_img_h         dd          800.0

align 16
g_img_conv_mask db          8,4,0,12,12 dup 0x80
g_0_0           dd          4 dup 0.0
g_0_5           dd          4 dup 0.5
g_1_0           dd          4 dup 1.0
g_255_0         dd          4 dup 255.0
;-------------------------------------------------------------------------------
